# coding: utf-8
from pathlib import Path
from typing import Literal

from PySide6.QtCore import Qt, QUrl, QFile, Signal, QPoint
from PySide6.QtGui import QColor, QDesktopServices, QFontMetrics
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QFileDialog
from qfluentwidgets import BodyLabel, SingleDirectionScrollArea, CaptionLabel, setFont, CardWidget, HorizontalSeparator, \
    TransparentToolButton, FluentIcon as FIF, ToolTipFilter, VBoxLayout, InfoBar, MaskDialogBase, MessageBox, RoundMenu, \
    Action

from common import History, signalBus
from components import CustomSimpleMediaPlayBar, NoDataCard


class ToolTipButton(TransparentToolButton):
    def _postInit(self):
        self.installEventFilter(ToolTipFilter(self))


class HistoryPlayBar(CardWidget):
    deleted = Signal(CardWidget, str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.data = {}
        self.verticalLayout = QVBoxLayout(self)
        self.horizontalLayout = QHBoxLayout()
        self.titleLabel = BodyLabel(self)
        self.openDirButton = ToolTipButton(FIF.FOLDER, self)
        self.saveAsButton = ToolTipButton(FIF.SAVE_AS, self)
        self.deleteButton = ToolTipButton(FIF.DELETE, self)
        self.descriptionLabel = CaptionLabel(self)
        self.simpleMediaPlayBar = CustomSimpleMediaPlayBar(self)

        setFont(self.titleLabel, 16)
        self.descriptionLabel.setTextColor(QColor(0, 0, 0, 200), QColor(255, 255, 255, 200))

        self.setObjectName('HistoryPlayBar')
        self.openDirButton.setToolTip('打开文件所在目录')
        self.saveAsButton.setToolTip('另存为')
        self.deleteButton.setToolTip('删除')

        self.verticalLayout.setContentsMargins(10, 8, 10, 8)
        self.verticalLayout.setSpacing(5)
        self.verticalLayout.setAlignment(Qt.AlignmentFlag.AlignVCenter)
        self.horizontalLayout.addWidget(self.titleLabel)
        self.horizontalLayout.addStretch(1)
        self.horizontalLayout.addWidget(self.openDirButton)
        self.horizontalLayout.addWidget(self.saveAsButton)
        self.horizontalLayout.addWidget(self.deleteButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(self.descriptionLabel)
        self.verticalLayout.addWidget(self.simpleMediaPlayBar)
        self.setFixedHeight(self.verticalLayout.sizeHint().height())

        self.saveAsButton.clicked.connect(self.onSaveAsButtonClicked)
        self.deleteButton.clicked.connect(self.onDeleteButtonClicked)

    def setData(self, data: dict):
        """
        设置历史记录数据
        :param data: {'name': str, 'text': str, 'source': str}
        """
        self.data = data
        self.titleLabel.setText(data.get('name', '未知'))
        description = QFontMetrics(self.descriptionLabel.font()).elidedText(
            data.get('text', '').replace('\n', '').replace('\r', '').replace(' ', ''), Qt.TextElideMode.ElideRight,
            self.descriptionLabel.width())
        self.descriptionLabel.setText(description)
        self.simpleMediaPlayBar.player.setSource(QUrl.fromLocalFile(data.get('source', '')))
        self.openDirButton.clicked.connect(
            lambda: QDesktopServices.openUrl(Path(data.get('source', '')).parent.as_uri()))

    def onSaveAsButtonClicked(self):
        menu = RoundMenu(parent=self)
        menu.addAction(Action('MP3 文件', self, triggered=lambda: self.onSaveAs('.mp3')))
        menu.addAction(Action('VTT 文件', self, triggered=lambda: self.onSaveAs('.vtt')))
        menu.addAction(Action('SRT 文件', self, triggered=lambda: self.onSaveAs('.srt')))

        x = (self.saveAsButton.width() - menu.width()) // 2 + 10
        pos = self.saveAsButton.mapToGlobal(QPoint(x, self.saveAsButton.height()))
        menu.exec(pos)

    def onSaveAs(self, tp: Literal['.vtt', '.srt', '.mp3']):
        file_name, _ = QFileDialog.getSaveFileName(
            self, '另存为', '', f'文件 (*{tp})',
            options=QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks
        )
        if file_name:
            source = self.data.get('source', '')

            source = Path(source).with_suffix(tp).as_posix()
            QFile.copy(source, file_name)

    def onDeleteButtonClicked(self):
        """
        点击删除按钮
        """
        message_box = MessageBox(
            title='确认删除',
            content=f'确认删除该条记录吗？\n 该操作不可恢复。\n {self.data.get("source", "")}',
            parent=self.window()
        )
        message_box.setClosableOnMaskClicked(True)
        message_box.setDraggable(True)
        if message_box.exec():
            self.simpleMediaPlayBar.player.stop()
            self.simpleMediaPlayBar.player.setSource(QUrl(''))
            self.deleted.emit(self, self.data.get('source', ''))

    def resizeEvent(self, event):
        description = QFontMetrics(self.descriptionLabel.font()).elidedText(
            self.data.get('text', '').replace('\n', '').replace('\r', '').replace(' ', ''), Qt.TextElideMode.ElideRight,
            self.width() - 30)
        self.descriptionLabel.setText(description)
        super().resizeEvent(event)


class HistoryInterface(SingleDirectionScrollArea):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.scrollWidget = QWidget()
        self.verticalLayout = VBoxLayout(self.scrollWidget)
        self.horizontalLayout = QHBoxLayout()
        self.titleLabel = BodyLabel('转换历史', self.scrollWidget)
        self.reloadButton = ToolTipButton(FIF.UPDATE, self.scrollWidget)
        self.noDataCard = NoDataCard(self.scrollWidget)

        self.__initWidgets()
        self.__initHistory()
        signalBus.reloadHistory.connect(self.reloadHistory)
        self.reloadButton.clicked.connect(
            lambda: (self.reloadHistory(), InfoBar.success('', '重新加载成功', parent=self.window())))

    def __initHistory(self):
        historys = History().history
        for history in historys:
            history_play_bar = HistoryPlayBar(self.scrollWidget)
            history_play_bar.setData(history)
            history_play_bar.deleted.connect(self.deleteHistory)
            self.verticalLayout.addWidget(history_play_bar)
        self._adjustNoDataCard()

    def __initWidgets(self):
        self.setObjectName('HistoryInterface')
        self.scrollWidget.setAutoFillBackground(False)
        self.setWidget(self.scrollWidget)
        self.setWidgetResizable(True)
        self.enableTransparentBackground()

        setFont(self.titleLabel, 20)
        self.reloadButton.setToolTip('重新加载')

        self.verticalLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.verticalLayout.setContentsMargins(0, 0, 10, 10)
        self.horizontalLayout.addWidget(self.titleLabel)
        self.horizontalLayout.addStretch(1)
        self.horizontalLayout.addWidget(self.reloadButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(HorizontalSeparator(self.scrollWidget))
        self.verticalLayout.addWidget(self.noDataCard, 0, Qt.AlignmentFlag.AlignCenter)

    def clearHistory(self):
        """
        清空历史记录
        """
        cards = self.findChildren(HistoryPlayBar, 'HistoryPlayBar')
        while cards:
            card = cards.pop()
            self.verticalLayout.deleteWidget(card)

    def reloadHistory(self):
        """
        重新加载历史记录
        """
        self.clearHistory()
        self.__initHistory()

    def deleteHistory(self, card: HistoryPlayBar, source: str):
        """
        删除历史记录
        """
        exists = QFile.exists(source)
        if not exists:
            self.verticalLayout.deleteWidget(card)
            History().remove(source)
            InfoBar.warning('', f'文件不存在, 历史记录已删除\n {source}', duration=3000, parent=self.window())
            return
        if not QFile.remove(source):
            InfoBar.error('', f'文件删除失败\n {source}', duration=3000, parent=self.window())
        else:
            vtt_source = Path(source).with_suffix('.vtt').as_posix()
            srt_source = Path(source).with_suffix('.srt').as_posix()
            QFile.remove(vtt_source)
            QFile.remove(srt_source)
            self.verticalLayout.deleteWidget(card)
            History().remove(source)
            InfoBar.success('', '删除成功', parent=self.window())

        self._adjustNoDataCard()

    def _adjustNoDataCard(self):
        """
        调整无数据卡片的显示状态
        """
        if not self.findChild(HistoryPlayBar, 'HistoryPlayBar'):
            self.noDataCard.setVisible(True)
        else:
            self.noDataCard.setVisible(False)
